#!/usr/bin/perl 
use strict;
use Getopt::Long;
use DBI;
################################################################################
## Monolith Toolkit for MySQL
## NAME: mt-check-replication.pl
## DATE: 2008-10-14
## AUTHOR: Matt Reid
## WEBSITE: http://monolith-mysql.com && http://themattreid.com 
## EMAIL: themattreid@gmail.com
## LICENSE: BSD http://www.opensource.org/licenses/bsd-license.php
################################################################################
## Copyright 2008 Matt Reid
## All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##################################################################################
#
## WHAT THIS SCRIPT DOES #########################################################
#This script checks replication status and reports via XML.
#
###########################################
#Set your options here please
###########################################
my $opt = { 
                'host' => 'host', #hostname or IP 
                'c' => 7200,      #critical seconds behind master
                'w' => 5400,      #warning seconds behind master
                'user' => 'user', #username
                'pass' => 'pass'  #password
                };

## END OF USER SETTINGS
###########################################
#
GetOptions($opt, "host=s", "c=i", "w=i", "user=s", "pass=s", "help");

sub get_status {
    my $HOST = $opt>{'host'};
    my $USER = $opt->{'user'};
    my $PASS = $opt->{'pass'};

    my $dbh = DBI->connect("DBI:mysql:host=$HOST",$USER,$PASS) or die "CRIT: cannot connect to $HOST. Exiting.";
    if (not $dbh) {
        print "UNKNOWN: cannot connect to $HOST";
        exit 3;
    }
    my $SQL = "SHOW SLAVE STATUS";
    my $state = $dbh->prepare($SQL);
    my $execSql = $state->execute;
    my $result = $state->fetchrow_hashref;
    return $result;
}

sub report {
    my $status = undef;
    my $error = undef;
    my $data = 0;
    my $slave = get_status();
    my $Seconds_Behind_Master = $slave->{'Seconds_Behind_Master'};
    my $Slave_SQL_Running = $slave->{'Slave_SQL_Running'};
    my $Slave_IO_Running = $slave->{'Slave_IO_Running'};
    my $crit = $opt->{'c'};
    my $warn = $opt->{'w'};
    my $date =localtime();
    my $status = "OK";

    if (($Seconds_Behind_Master >= $crit) || ($Slave_SQL_Running ne 'Yes') || ($Slave_IO_Running ne 'Yes')) {
        $status = 'CRITICAL';
        $error = 2;
        $data = 2;
    } 
    elsif ($Seconds_Behind_Master >= $warn) {
        $status = 'WARNING';
        $error = 1;
        $data = 1;
    }
                
    my $output = sprintf "<data>
<hash>
<item key=\"data\">$data</item>
<item key=\"status_message\">$status: Behind: $Seconds_Behind_Master sec, Slave IO: $Slave_IO_Running, Slave SQL: $Slave_SQL_Running, Date: $date </item>
</hash>
</data>";
    
    print "$output";
    exit $error;
}


if(defined($opt->{'help'}) || !defined($opt)) {
    print <<HELP;
mt-check-replication
--------------------------
Monolith Toolkit
http://monolith-mysql.com
2008-10-15
--------------------------
This script checks replication status and reports via XML.
Tested on MySQL 4.1, 5.0

Options:
host      =    ip_address
c         =    critical difference in seconds
w         =    warning difference in seconds
user      =    database username
pass      =    database password
--------------------------
HELP
exit;
}


report();
